/* $Id: ns2.x,v 1.38 2006/02/17 14:32:26 gaburici Exp $ */

/* $Id: common2.x,v 1.23 2006/02/17 14:32:26 gaburici Exp $ */

const TRUE=1;
typedef unsigned hyper uint64_t;
typedef hyper int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;


const MAX_FIDSIZE = 256; /* = MAX_MFS_PATH */

typedef string server_name<>;
typedef string path_name<>;
typedef string file_name<>;
typedef string snapshot_tag<>;
typedef string tns_tag<>;
typedef string snap_annot<>;

union hashed_cred switch (bool cred_follows) {
	case TRUE: opaque bytes<>;
	default: void;			/* in case none are required */
};

/*
	snpashot_basic: What a server holds

 	I could use some numeric ids for snapshots, but I think this more in line with
	the spirit of naming everything in motefs.

	The cred is calculated as:

	H(hide_n | ... H(hide_1 | H (path.cred | tag)) ... )

	Thus given a basic_snapshot a client can further hide paths from it, and the server
	can still verify the credential.
*/

struct snapshot_basic { 
	server_name		server;
	path_name    	path;
	snapshot_tag 	tag;
	path_name		hide<>;
	hashed_cred		cred;
};


enum permission_type {
	PERM_READ   = 1,
	PERM_WRITE  = 2,
	PERM_APPEND = 3
};


/* mfs2 mount & ns2 mountone shared data structures */

typedef uint64_t mfs2_tid;
typedef uint64_t mfs2_snid;
typedef uint64_t mfs2_sfid;  /* server inode id is also passed to the mote tool */
typedef uint32_t cli_nsid;

enum mfs2_mount_type {
	MFS2MOUNT_FROZEN = 2,
	MFS2MOUNT_SNAP = 3
};

enum mfs2_mntind_type {
	MFS2MOUNT_LATEST = 4,
	MFS2MOUNT_TAGNS = 5
};


struct mfs2_snap_spec {
/*	snapshot_tag 	tag; */
	mfs2_snid       snid;
/*	path_name		hide<>;*/
};

union mfs2_mount_spec switch (mfs2_mount_type type) {
	case MFS2MOUNT_FROZEN: 	mfs2_tid tid;
	case MFS2MOUNT_SNAP:	mfs2_snap_spec snap_spec;
};


struct mfs2_tag_spec {
	tns_tag tag;
	bool    live;
};

union mfs2_mntind_spec switch (mfs2_mount_type type) {
	case MFS2MOUNT_LATEST:	path_name path;
	case MFS2MOUNT_TAGNS:	mfs2_tag_spec tag_spec;
};


enum mfs2_mntdsc_type {
	MFS2MOUNT_DIRECT    = 901,
	MFS2MOUNT_INDIRECT  = 902
};

union mfs2_mount_desc switch (mfs2_mntdsc_type type) {
	case MFS2MOUNT_DIRECT:		mfs2_mount_spec  dspec;
	case MFS2MOUNT_INDIRECT:	mfs2_mntind_spec ispec;
};

struct mfs2_mountable {
	server_name server;
	mfs2_mount_desc	desc;
	path_name path;
};

enum mfs2_tag_test_type {
	MFS2TAG_NONE	= 0,
	MFS2TAG_SPEC	= 1,
	MFS2TAG_TAG		= 2
};

union mfs2_tag_test switch(mfs2_tag_test_type ttype) {
	case MFS2TAG_NONE:	void;
	case MFS2TAG_SPEC:	mfs2_mount_spec spec;
	case MFS2TAG_TAG:	tns_tag tag;
};

typedef path_name relative_mount_point; /* relative to snapshot_aggregate root */

enum mountable_type {
	SNAPSHOT_BASIC = 0,
	SNAPSHOT_AGGREGATE = 1
};

typedef opaque credentials<>;


const NFS3_FHSIZE = 64;
struct ns2_vroot {
	int32_t nsnum;
	mfs2_sfid inum;
};

enum ns2_stat {
	NS2_OK = 0,
	NS2_ERR = 1
};


union mount_res switch (ns2_stat status) {
case NS2_OK:
	ns2_vroot vroot;
default:
	void;
};


union freeze_res switch (ns2_stat status) {
case NS2_OK:
	mfs2_tid tid;
default:
	void;
};


union snapone_res switch (ns2_stat status) {
case NS2_OK:
	mfs2_mountable mtbl; /* a snapshot really, but include the host */
default:
	void;
};

enum mount_flags {
	NS2_FORCE_ASYNC = 1
};

typedef string nsinfo_res<>;

/* Credentials are passed in clear locally on the client.*/
program NAMESPACE {
  version NAMESPACE_VERS_2 {
    mount_res MOUNTONE(server_name server, path_name what, path_name mount_point, 
					   mfs2_mount_desc spec, mount_flags flags, credentials c) = 1;
    ns2_stat REMOUNT(uint32_t anchor_id, mfs2_mount_spec spec, credentials c) = 101;
	freeze_res FREEZE(uint32_t mount_point) = 3;
    snapone_res SNAPONE(uint32_t anchor_id, path_name path, bool rekey, snap_annot annot) = 104;
    int PROBENS(uint32_t anchor_id) = 105;
/*    int DERIVE(server_name server, mfs2_snid sid, string label, string base, string out_file) = 106; */
	int FLUSHONE(uint32_t anchor_id, uint32_t nelems) = 107;
	uint64_t INCA(void) = 108;
	ns2_stat TAG(uint32_t anchor_id, tns_tag tag, mfs2_tag_test test) = 109;
	nsinfo_res NSINFO(int32_t nsnum) = 110;
	ns2_stat MOUNTACK(int32_t nsnum) = 111;
    ns2_stat UMOUNT(int32_t nsnum, bool sync) = 2;
	/* unnamed struct test */
	struct { int x; } FOO(void) = 999;
	/* unnamed args test */
	int BAR(int, int x, int) = 990;
  } = 2;
} = 400000;

